﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Configuration;

using ComunesMGI.DataTypes;
using ComunesMGI.Enum;
using ComunesMGI.Constantes;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System.IO;

namespace MGI.AccesoDatos.AccesoSP
{
    class SPAcceso
    {
        static public void ConectarLista(string urlSistema, Lista lista, ref SPSite mySite, ref SPWeb myWeb, ref SPList spLista)
        {
            SPEventLog.WriteLog("Conectado: " + urlSistema);
            try
            {
                if (mySite == null)
                {
                    mySite = new SPSite(urlSistema);
                }
            }
            catch (Exception e)
            {
                SPEventLog.WriteLog("No se pudo conectar al sitio Sharepoint: " + e.Message);
                throw new ComunesMGI.Excepciones.SPConeccionFallida("No se pudo conectar al sitio Sharepoint: " + e.Message);
            }
            SPEventLog.WriteLog("Intentando abrir web para acceder a las listas");
            try
            {
                if (myWeb == null)
                {
                    myWeb = mySite.OpenWeb();
                }
            }
            catch (Exception e)
            {
                SPEventLog.WriteLog("No se pudo hacer la apertura:" + e.Message);
                throw new ComunesMGI.Excepciones.SPConeccionFallida("No se pudo abrir el web:" + e.Message);
            }

            if (myWeb != null)
            {
                if (myWeb.Permissions != null)
                {
                    SPEventLog.WriteLog("Se logró apertura correctamente");
                    SPEventLog.WriteLog("Usuario con el que se conectó: " + myWeb.CurrentUser.LoginName);
                    SPEventLog.WriteLog("Permisos de Acceso: ");
                    foreach (SPPermission permiso in myWeb.Permissions)
                    {
                        SPEventLog.WriteLog("Permisos: " + permiso.ToString());
                    }
                }
                else
                {
                    SPEventLog.WriteLog("No hay permisos");
                }
            }
            else
            {
                SPEventLog.WriteLog("No se pudo hacer la apertura");
                throw new ComunesMGI.Excepciones.SPConeccionFallida("No se pudo abrir el web");
            }

            SPEventLog.WriteLog("Intentando obtener la lista de Sharepoint: " + lista);
            try
            {
                spLista = myWeb.Lists[SPAcceso.LeerListaIdioma(lista, myWeb.Language)];
            }
            catch (Exception e)
            {
                SPEventLog.WriteLog("Lista " + lista + " no encontrada");
                throw new ComunesMGI.Excepciones.SPObjetoInexistente("Lista " + lista + " no encontrada: " + e.Message);
            }



            if (spLista == null)
            {
                SPEventLog.WriteLog("Lista " + lista + " no encontrada");
                throw new ComunesMGI.Excepciones.SPObjetoInexistente("Lista " + lista + " no encontrada");
            }
            else
            {
                SPEventLog.WriteLog("Se obtuvo correctamente la lista: " + spLista.Title + " " + spLista.ID);
            }
        }

        static public void Conectar(string urlSistema, ref SPSite mySite, ref SPWeb myWeb)
        {
            SPEventLog.WriteLog("Intentando conectar con sitio Sharepoint: " + urlSistema);
            try
            {
                mySite = new SPSite(urlSistema);
            }
            catch (Exception e)
            {
                SPEventLog.WriteLog("No se pudo conectar al sitio Sharepoint: " + e.Message);
                throw new ComunesMGI.Excepciones.SPConeccionFallida("No se pudo conectar al sitio Sharepoint: " + e.Message);
            }

            SPEventLog.WriteLog("Conectado: " + urlSistema);
            SPEventLog.WriteLog("Intentando abrir web para acceder a las listas");
            myWeb = mySite.OpenWeb();
            if (myWeb != null)
            {
                if (myWeb.Permissions != null)
                {
                    SPEventLog.WriteLog("Se logró apertura correctamente");
                    SPEventLog.WriteLog("Usuario con el que se conectó: " + myWeb.CurrentUser.LoginName);
                    SPEventLog.WriteLog("Permisos de Acceso: ");
                    foreach (SPPermission permiso in myWeb.Permissions)
                    {
                        SPEventLog.WriteLog("   " + permiso.ToString());
                    }

                }
            }
            else
            {
                SPEventLog.WriteLog("No se pudo hacer la apertura");
                throw new ComunesMGI.Excepciones.SPConeccionFallida("No se pudo abrir el web");
            }
        }

        static public void Desconectar(ref SPSite mySite, ref SPWeb myWeb)
        {
            myWeb.Close();
            mySite.Close();
            myWeb.Dispose();
            mySite.Dispose();
        }




        /// <summary>
        /// Dada una lista de sharepoint y una lista de datacampo 
        /// conteniendo nombre de los campos, tipo y un valor para los 
        /// mismos, se realiza el alta en sharepoint con la información. 
        /// Se usa tambien el sitio sharepoint para obtener información sobre
        /// la conversión de fechas del formato "dd-mm-aaaa hh:mm" a
        /// cualquier formato configurado en el sharepoint.
        /// También se pueden adjuntar archivos.
        /// 
        /// Retorna ID y otra información de lo creado.
        /// </summary>
        /// <param name="myWeb"></param>
        /// <param name="spLista"></param>
        /// <param name="campos"></param>
        /// <param name="archivos"></param>
        /// <returns>DataAltaIncidente</returns>
        static public string[] Impactar(SPWeb myWeb, SPList spLista, List<DataCampo> campos, Lista tipoLista)
        {
            SPListItem newItem = spLista.Items.Add();
            foreach (DataCampo dataCampo in campos)
            {
                switch (dataCampo.Tipo)
                {
                    case CampoSharepoint.DateTime:
                        string[] fechaHora = dataCampo.Valor.Split(' ');
                        newItem[SPAcceso.LeerCampoIdioma(tipoLista, dataCampo.Titulo, myWeb.Language)] = SPUtility.ParseDate(myWeb, fechaHora[0], fechaHora[1], false);
                        break;
                    case CampoSharepoint.User:
                        if (dataCampo.Valor != null)
                        {
                            SPUser spUser = myWeb.AllUsers[dataCampo.Valor];
                            newItem[SPAcceso.LeerCampoIdioma(tipoLista, dataCampo.Titulo, myWeb.Language)] = spUser;
                        }
                        break;
                    default:
                        newItem[SPAcceso.LeerCampoIdioma(tipoLista, dataCampo.Titulo, myWeb.Language)] = dataCampo.Valor;
                        break;
                }
            }
            newItem.Update();

            //obtiene la parte final de la url conteniendo el nombre de la lista
            int ini = spLista.DefaultViewUrl.LastIndexOf(ConstantesMGI.PageDefaultUrlLista + "/");
            //elimina la vista por defecto porque no permite acceso directo a la url del item
            //en su lugar usamos DispForm.aspx
            int largo = spLista.DefaultViewUrl.LastIndexOf("/") - ini;
            string parteLista = spLista.DefaultViewUrl.Substring(ini, largo) + "/" + ConstantesMGI.PageDefaultUrlListaItems;
            string url = spLista.ParentWeb.Url + "/" + parteLista + "?ID=" + newItem[SPAcceso.LeerCampoIdioma(tipoLista, "ID", myWeb.Language)].ToString();
            string[] result = new string[2];
            result[0] = newItem.ID.ToString();
            result[1] = url;
            return result;
        }










        /*
         
   <Where>
    <And>
       <And>
           <And>
              <Eq>
                <FieldRef Name='LastName' />
                <Value Type='Text'>Janssens</Value>
              </Eq>
              <Geq>
                <FieldRef Name='Age' />
                <Value Type='Number'>21</Value>
              </Geq>
           </And>
           <Lt>
             <FieldRef Name='Age' />
             <Value Type='Number'>60</Value>
           </Lt>
       </And>
        <Eq>
          <FieldRef Name='Country' />
          <Value Type='Lookup'>Belgium</Value>
        </Lt>
    </And>
   </Where>
         
         */







        /// <summary>
        /// Retorna los elementos de la lista que tienen los valores indicados en
        /// la lista de datacampos
        /// </summary>
        List<string[]> getItemCondicion(Lista SPLista, List<DataCampo> condicion, List<DataCampo> obtener)
        {
          
            
            
            
            
            
            
            
            /*
            SPSite mySite = new SPSite(sitioSistema);
            SPWeb myWeb = mySite.OpenWeb();
            SPList spLista = myWeb.Lists[ConstantesMGI.NomListaTareas];
            SPListItem spItem = spLista.Items.GetItemById( idTarea);

            string mail = null;
            if (SPUtility.IsLoginValid(mySite, usuario.Nombre))
            {
                SPUser spUser = myWeb.AllUsers[usuario.Nombre];
                spItem["Asignado a"] = spUser;
                spItem["IDOriginal"] = idIncidente;
                spItem.Update();
                mail = spUser.Email;
            }*/
            return null;
        }

        


        /// <summary>
        /// Obtiene los nombres de los campos desde el archivo xml de idiomas
        /// 
        /// </summary>
        /// <param name="nomCliente">Nombre del cliente</param>
        /// <param name="nomSistema">Nombre del sistema</param>
        /// <param name="tipoLista">Tipo de lista de la que se quiere obtener los campos</param>
        /// <returns>Lista de dataCampo conteniendo los nombres de los campos</returns>
        static public string LeerCampoIdioma(Lista tipoLista, string nomCampo, uint codigoIdioma)
        {
            //Se obtiene la path del directorio con los xml de los sitemas de los clientes
            string pathClientesInfo = ConfigurationManager.AppSettings.Get("pathInfoClientes");
            string pathInfoIdioma = pathClientesInfo + "\\SPMap.xml";
            //DirectoryInfo dirInfoIdioma = new DirectoryInfo(pathInfoIdioma);
            XmlDocument xDoc = null;
            xDoc = new XmlDocument();
            try
            {
                xDoc.Load(pathInfoIdioma);
            }
            catch (Exception e)
            {
                throw new Exception("No se pudo abrir el xml de idiomas en: " + pathInfoIdioma + " " + e.Message);
            }
            string xpath = null;

            if (tipoLista == Lista.Incidentes)
            {
                xpath = "//listas/Incidentes/campos/campo[@nombre = '" + nomCampo + "']/nombre" + codigoIdioma;
            }
            else
            {
                xpath = "//listas/Tareas/campos/campo[@nombre = '" + nomCampo + "']/nombre" + codigoIdioma;
            }
            XmlNodeList nodo = xDoc.SelectNodes(xpath);
            return nodo[0].InnerText;
        }


        internal static object LeerCampoChoiceIdioma(Lista lista, string p, string estado, uint p_4)
        {
            //Se obtiene la path del directorio con los xml de los sitemas de los clientes
            string pathClientesInfo = ConfigurationManager.AppSettings.Get("pathInfoClientes");
            string pathInfoIdioma = pathClientesInfo + "\\SPMap.xml";
            //DirectoryInfo dirInfoIdioma = new DirectoryInfo(pathInfoIdioma);
            XmlDocument xDoc = null;
            xDoc = new XmlDocument();
            try
            { 
                xDoc.Load(pathInfoIdioma);
            }
            catch (Exception e)
            {
                throw new Exception("No se pudo abrir el xml de idiomas en: " + pathInfoIdioma + " " + e.Message);
            }
            string xpath = null;
            /*
            if (tipoLista == Lista.Incidentes)
            {
                xpath = "//listas/Incidentes/campos/campo[@nombre = '" + nomCampo + "']/nombre" + codigoIdioma;
            }
            else
            {
                xpath = "//listas/Tareas/campos/campo[@nombre = '" + nomCampo + "']/nombre" + codigoIdioma;
            }*/
            XmlNodeList nodo = xDoc.SelectNodes(xpath);
            return nodo[0].InnerText;
        }







        /// <summary>
        /// Obtiene los nombres de los campos desde el archivo xml de idiomas
        /// 
        /// </summary>
        /// <param name="nomCliente">Nombre del cliente</param>
        /// <param name="nomSistema">Nombre del sistema</param>
        /// <param name="tipoLista">Tipo de lista de la que se quiere obtener los campos</param>
        /// <returns>Lista de dataCampo conteniendo los nombres de los campos</returns>
        static public string LeerListaIdioma(Lista tipoLista, uint codigoIdioma)
        {
            //Se obtiene la path del directorio con los xml de los sitemas de los clientes
            string pathClientesInfo = ConfigurationManager.AppSettings.Get("pathInfoClientes");
            string pathInfoIdioma = pathClientesInfo + "\\SPMap.xml";
            //DirectoryInfo dirInfoIdioma = new DirectoryInfo(pathInfoIdioma);
            XmlDocument xDoc = null;
            xDoc = new XmlDocument();
            try
            {
                xDoc.Load(pathInfoIdioma);
            }
            catch (Exception e)
            {
                throw new Exception("No se pudo abrir el xml de idiomas en: " + pathInfoIdioma + " " + e.Message);
            }
            string xpath = null;

            if (tipoLista == Lista.Incidentes)
            {
                xpath = "//listas/Incidentes/titulo" + codigoIdioma;
            }
            else
            {
                xpath = "//listas/Tareas/titulo" + codigoIdioma;
            }
            XmlNodeList nodo = xDoc.SelectNodes(xpath);
            return nodo[0].InnerText;
        }







        /*

        private static string CampoPorIdioma(string nomCampo, Lista listaSharepoint, uint idioma) 
        {
            switch (idioma)
            {
                case 1033: //código english
                    {
                        switch (listaSharepoint)
                        {
                            case Lista.Incidentes:
                                {
                                    switch (nomCampo)
                                    {
                                        case "ID": return "ID";
                                            
                                        case "Título": return "Title";
                                            
                                        case "Descripción": return "Description";
                                            
                                        case "Reportado por": return "Reported by";
                                            
                                        case "Fecha Propuesto": return "Reported Date";
                                            
                                        case "WP": return "WP";
                                            
                                        case "Asignado a": return "Assigned To";
                                            
                                        case "Prioridad": return "Priority";
                                            
                                        case "Orden Prioridad": return "Priority Order";
                                            
                                        case "Categoría": return "Category";
                                            
                                        case "Estado": return "Status";
                                            
                                        case "Comentario": return "Comment";
                                            
                                        case "Fecha Cierre": return "Due Date";
                                            
                                        case "Resolución": return "Resolution";
                                            
                                        case "Agregar asunto relacionado": return "Add Related Issue";
                                            

                                        //english retorna lo mismo

                                        case "Title": return nomCampo;
                                            
                                        case "Description": return nomCampo;
                                            
                                        case "Reported by": return nomCampo;
                                            
                                        case "Reported Date": return nomCampo;
                                            

                                        case "Assigned To": return nomCampo;
                                            
                                        case "Priority": return nomCampo;
                                            
                                        case "Priority Order": return nomCampo;
                                            
                                        case "Category": return nomCampo;
                                            
                                        case "Status": return nomCampo;
                                            
                                        case "Comment": return nomCampo;
                                            
                                        case "Due Date": return nomCampo;
                                            
                                        case "Resolution": return nomCampo;
                                            
                                        case "Add Related Issue": return nomCampo;
                                            
                                        default: return null;
                                            
                                    }
                                }

                            case Lista.Tareas:
                                {
                                    switch (nomCampo)
                                    {
                                        case "Title": return nomCampo;
                                            
                                        case "Priority": return nomCampo;
                                            
                                        case "Status": return nomCampo;
                                            
                                        case "% Complete": return nomCampo;
                                            
                                        case "Assigned To": return nomCampo;
                                            
                                        case "Description": return nomCampo;
                                            
                                        case "Start Date": return nomCampo;
                                            
                                        case "Due Date": return nomCampo;
                                            

                                        case "Título": return "Title";
                                            
                                        case "Prioridad": return "Priority";
                                            
                                        case "Estado": return "Status";
                                            
                                        case "% completado": return "% Complete";
                                            
                                        case "Asignado a": return "Assigned To";
                                            
                                        case "Descripción": return "Description";
                                            
                                        case "Fecha de comienzo": return "Start Date";
                                            
                                        case "Fecha de vencimiento": return "Due Date";

                                        default: return null;
                                            
                                    }
                                }

                            default:
                                break;

                        }

                    }
                    break;
                case 1034: //codigo español
                    {
                        switch (listaSharepoint)
                        {
                            case Lista.Incidentes:
                                {
                                    switch (nomCampo)
                                    {
                                        case "ID": return nomCampo;
                                            
                                        case "Título": return nomCampo;
                                            
                                        case "Descripción": return nomCampo;
                                            
                                        case "Reportado por": return nomCampo;
                                            
                                        case "Fecha Propuesto": return nomCampo;
                                            
                                        case "WP": return nomCampo;
                                            
                                        case "Asignado a": return nomCampo;
                                            
                                        case "Prioridad": return nomCampo;
                                            
                                        case "Orden Prioridad": return nomCampo;
                                            
                                        case "Categoría": return nomCampo;
                                            
                                        case "Estado": return nomCampo;
                                            
                                        case "Comentario": return nomCampo;
                                            
                                        case "Fecha Cierre": return nomCampo;
                                            
                                        case "Resolución": return nomCampo;
                                            
                                        case "Agregar asunto relacionado": return nomCampo;
                                            

                                        //english retorna lo mismo

                                        case "Title": return "Título";
                                            
                                        case "Description": return "Descripción";
                                            
                                        case "Reported by": return "Reportado por";
                                            
                                        case "Reported Date": return "Fecha Propuesto";
                                            

                                        case "Assigned To": return "Asignado a";
                                            
                                        case "Priority": return "Prioridad";
                                            
                                        case "Priority Order": return "Orden Prioridad";
                                            
                                        case "Category": return "Categoría";
                                            
                                        case "Status": return "Estado";
                                            
                                        case "Comment": return "Comentario";
                                            
                                        case "Due Date": return "Fecha Cierre";
                                            
                                        case "Resolution": return "Resolución";
                                            
                                        case "Add Related Issue": return "Agregar asunto relacionado";
                                            

                                        default: return null;
           
                                    }



                                }

                            case Lista.Tareas:
                                {
                                    switch (nomCampo)
                                    {
                                        case "Título": return nomCampo;
                                            
                                        case "Prioridad": return nomCampo;
                                            
                                        case "Estado": return nomCampo;
                                            
                                        case "% completado": return nomCampo;
                                            
                                        case "Asignado a": return nomCampo;
                                            
                                        case "Descripción": return nomCampo;
                                            
                                        case "Fecha de comienzo": return nomCampo;
                                            
                                        case "Fecha de vencimiento": return nomCampo;
                                            

                                        case "Title": return "Título";
                                            
                                        case "Priority": return "Prioridad";
                                            
                                        case "Status": return "Estado";
                                            
                                        case "% Complete": return "% completado";
                                            
                                        case "Assigned To": return "Asignado a";
                                            
                                        case "Description": return "Descripción";
                                            
                                        case "Start Date": return "Fecha de comienzo";
                                            
                                        case "Due Date": return "Fecha de vencimiento";
                                            
                                        default:
                                            return null;
                                    }
                                }
                                
                            default:
                                break;
                        }
                    }
                    break;
                default:
                    {
                        switch (listaSharepoint)
                        {
                            case Lista.Incidentes:
                                {
                                    switch (nomCampo)
                                    {
                                        case "ID": return nomCampo;
                                            
                                        case "Título": return nomCampo;
                                            
                                        case "Descripción": return nomCampo;
                                            
                                        case "Reportado por": return nomCampo;
                                            
                                        case "Fecha Propuesto": return nomCampo;
                                            
                                        case "WP": return nomCampo;
                                            
                                        case "Asignado a": return nomCampo;
                                            
                                        case "Prioridad": return nomCampo;
                                            
                                        case "Orden Prioridad": return nomCampo;
                                            
                                        case "Categoría": return nomCampo;
                                            
                                        case "Estado": return nomCampo;
                                            
                                        case "Comentario": return nomCampo;
                                            
                                        case "Fecha Cierre": return nomCampo;
                                            
                                        case "Resolución": return nomCampo;
                                            
                                        case "Agregar asunto relacionado": return nomCampo;
                                            

                                        //english retorna lo mismo
                                        case "Title": return "Título";
                                            
                                        case "Description": return "Descripción";
                                            
                                        case "Reported by": return "Reportado por";
                                            
                                        case "Reported Date": return "Fecha Propuesto";
                                            
                                        case "Assigned To": return "Asignado a";
                                            
                                        case "Priority": return "Prioridad";
                                            
                                        case "Priority Order": return "Orden Prioridad";
                                            
                                        case "Category": return "Categoría";
                                            
                                        case "Status": return "Estado";
                                            
                                        case "Comment": return "Comentario";
                                            
                                        case "Due Date": return "Fecha Cierre";
                                            
                                        case "Resolution": return "Resolución";
                                            
                                        case "Add Related Issue": return "Agregar asunto relacionado";
                                            

                                        default: return null;
                                            
                                    }



                                }

                            case Lista.Tareas:
                                {
                                    switch (nomCampo)
                                    {
                                        case "Título": return nomCampo;
                                            
                                        case "Prioridad": return nomCampo;
                                            
                                        case "Estado": return nomCampo;
                                            
                                        case "% completado": return nomCampo;
                                            
                                        case "Asignado a": return nomCampo;
                                            
                                        case "Descripción": return nomCampo;
                                            
                                        case "Fecha de comienzo": return nomCampo;
                                            
                                        case "Fecha de vencimiento": return nomCampo;
                                            

                                        case "Title": return "Título";
                                            
                                        case "Priority": return "Prioridad";
                                            
                                        case "Status": return "Estado";
                                            
                                        case "% Complete": return "% completado";
                                            
                                        case "Assigned To": return "Asignado a";
                                            
                                        case "Description": return "Descripción";
                                            
                                        case "Start Date": return "Fecha de comienzo";
                                            
                                        case "Due Date": return "Fecha de vencimiento";
                                            
                                        default:
                                            return null;
                                    }
                                }

                            default:
                                break;
                        }
                    }
                    break;
            }
            return null;
        }
        */




    }















}
